package com.dongdongshop.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializeFilter;
import com.dongdongshop.page.PageBean;
import com.dongdongshop.pojo.TbItem;
import com.dongdongshop.service.ItemService;
import com.dongdongshop.util.Result;
import org.apache.dubbo.config.annotation.DubboReference;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.xcontent.XContent;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("Elasticsearch")
public class ElasticSearchController {

    @DubboReference
    private ItemService itemService;

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    //批量添加文档
    @RequestMapping("bulkAddItems")
    @ResponseBody
    public String bulkAddItems() throws IOException {
        BulkRequest bulkRequest = new BulkRequest();
        bulkRequest.timeout("10s");
        List<TbItem> itemList = itemService.selectItemList();
        //批量请求处理
        for (int i = 0; i < itemList.size(); i++) {
            bulkRequest.add(
                    //这里是数据信息
                    new IndexRequest("items_index")
                            .id("" + (i + 1))//没有设置id 会自动生成一个随机id
                            .source(JSON.toJSONString(itemList.get(i)), XContentType.JSON)
            );
        }
        BulkResponse bulk = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
        System.out.println(bulk.status());// ok
        return "ok";
    }

    @RequestMapping("toSearch")
    public String toSearch(String title, Model model) {
        model.addAttribute("title", title);
        return "search";
    }

    //高亮显示
    @RequestMapping("HighLightQuery")
    @ResponseBody
    public Result HighLightQuery(String title, @RequestParam(defaultValue = "1") Integer pageNum,
                                 @RequestParam(defaultValue = "1") Integer pageSize) {
        try {
            //搜索请求对象
            SearchRequest searchRequest = new SearchRequest("dongdongshop");
            //搜索元构建对象
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            //Query-match单字段模糊查询
            //模糊查询
            searchSourceBuilder.query(QueryBuilders.termQuery("title", title));
            //计算起始下标:(当前页数 - 1) * 页大小
            int index = (pageNum - 1) * pageSize;
            searchSourceBuilder.from(index);//from 表示记录开始的顺序
            searchSourceBuilder.size(pageSize);
            //像搜索请求 对象中设置搜索源
            searchRequest.source(searchSourceBuilder);

            //创建高亮显示对象
            HighlightBuilder highlightBuilder = new HighlightBuilder();
            //设置高亮前缀
            highlightBuilder.preTags("<span style='color:red'>");
            //设置高亮字段
            highlightBuilder.field("title");
            //设置高亮后缀
            highlightBuilder.postTags("<span>");
            //设置添加高亮
            searchSourceBuilder.highlighter(highlightBuilder);
            searchRequest.source(searchSourceBuilder);
            String queryJson = searchSourceBuilder.toString();
            SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            //搜索结果
            SearchHits hits = search.getHits();

            List list = new ArrayList<>();
            for (SearchHit hit : hits.getHits()) {
                //使用新的字段值(高亮)覆盖旧的字段值,源数据
                Map<String, Object> sourceAsMap = hit.getSourceAsMap();
                //高亮字段
                Map<String, HighlightField> highlightFieIds = hit.getHighlightFields();
                HighlightField name = highlightFieIds.get("title");
                //替换
                if (name != null) {
                    //获取当前高亮字段
                    Text[] fragments = name.fragments();
                    StringBuffer new_name = new StringBuffer();
                    for (Text str : fragments) {
                        new_name.append(str);
                    }
                    sourceAsMap.put("title", new_name.toString());
                    list.add(sourceAsMap);
                }
                System.out.println(sourceAsMap);
            }
            Long total = Long.valueOf(JSON.toJSONString(hits.getTotalHits().value));
            Long pageIndex = total % pageSize == 0 ? total / pageSize : total / pageSize + 1;//页码数
            Integer page = Integer.valueOf(pageIndex.toString());
            PageBean pageBean = new PageBean(pageNum, pageSize, total, page, list);
            return Result.OK().setData(pageBean);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.ERROR();
        }
    }


}
